#coding=utf-8
from uliweb import expose, decorators,functions
from uliweb.orm import get_model


def __begin__():
    from uliweb import function
    return function('require_login')()

@expose('/systems/<int:id>/functions')
class SysFunctionView(object):
    def __init__(self):
        self.model = get_model('sysfunction')
        
    def _create_query(self, url):
        """
        创建查询View
        """
        from uliweb.orm import get_model
        from uliweb.utils.generic import QueryView
        from uliweb.form import UnicodeField, SelectField
        from plugs.ui.jquery.jqcombobox.widgets import JQComboBoxField
        from plugs.ui.jquery.uimultiselect.widgets import UIMultiSelectField
        from query.forms import QueryForm
        from uliweb.utils.generic import ReferenceSelectField
        
        sequence_number = UnicodeField('功能点编号')
        status = UIMultiSelectField('启用状态', choices=settings.get_var('PARA/FUNCTION_USING_STATUS'))
        fields = ['category',('status', status),('sequence_number',sequence_number)]
        layout = [('category'),('status','sequence_number')]
        
        query = QueryView(self.model, ok_url=url, fields=fields, layout=layout, form_cls=QueryForm)
        return query
#    @expose('')
#    def list(self,id):
#        return redirect(url_for(SysFunctionView.functions_list,system=id))

    @expose('')
    def list(self,id):
        """
        功能点列表
        """
        
        from uliweb.utils.generic import ListView, get_sort_field
        from uliweb.orm import get_model
        from uliweb.core.html import Tag
        query = self._create_query(url_for(self.__class__.list, id=id))
        c = query.run()
#        print '=====',c
        pageno = int(request.values.get('page', 1)) - 1
        rows_per_page=int(request.values.get('rows', settings.get_var('PARA/ROWS_PER_PAGE', 10)))
        condition = None
        condition = self.model.c.system == int(id)
#        condition = (self.model.c.deleted == 0) & condition
        if c.get('category'):
            condition = (self.model.c.category==c['category']) & condition
        if c.get('status'):
            condition = (self.model.c.status.in_(c['system'])) & condition
        if c.get('sequence_number'):
            condition = self.model.c.sequence_number.like('%'+c['sequence_number']+'%') & condition
        
#        else:
#            c['system']
        def sequence_number(value, obj):
            return str(Tag('a', obj.sequence_number, href="/systems/functions/view/%d" % obj.id))
            
        order_by = get_sort_field(self.model) or []
        fields_convert_map = {'sequence_number':sequence_number}
        view = ListView(self.model, condition=condition, 
            table_width=False, fields_convert_map=fields_convert_map, 
            order_by=order_by, rows_per_page=rows_per_page, pageno=pageno)
        if 'data' in request.values:
            return json(view.json())
        elif 'download' in request.values:
            return view.download('sysfunction_list.xls', action='download', timeout=0,
                fields_convert_map=fields_convert_map, domain=settings.PARA.DOMAIN)
        else:
            result = view.run(head=True, body=False)
            result.update({'query_form':query.form, 'table':view, 'system_id':id})
            return result
        
    @expose('category')
    def category(self, id):
        """
        功能点分类列表
        """
        
        from uliweb.utils.generic import ListView
        
        Category = get_model('sysfunctioncategory')
        return {'categories':Category.filter(Category.c.system==int(id)), 'system_id':id}
    
    @expose('category_add')
    @decorators.check_role('sys_manager', system_id='id')
    def category_add(self, id):
        """
        添加功能点分类
        """
        
        from uliweb.utils.generic import AddView
        
        view = AddView('sysfunctioncategory', success_data=True, default_data={'system':int(id)})
        return view.run(json_result=True)
    
    @expose('category_del/<c_id>')
    @decorators.check_role('sys_manager', system_id='id')
    def category_del(self, id, c_id):
        """
        删除功能点分类
        """
        
        from uliweb.utils.generic import DeleteView
        
        C = get_model('sysfunctioncategory')
        obj = C.get((C.c.system==int(id)) & (C.c.id==int(c_id)))
        view = DeleteView('sysfunctioncategory', obj=obj)
        return view.run(json_result=True)
    
    @expose('category_edit')
    @decorators.check_role('sys_manager', system_id='id')
    def category_edit(self, id):
        """
        添加功能点分类
        """
        
        from uliweb.utils.generic import DeleteView
        
        c_id = request.POST.get('id')
        name = request.POST.get('new_value')
        if not name:
            return json({'is_error':True, 'error_text':"分类名称不能为空", 'html':''})
        C = get_model('sysfunctioncategory')
        obj = C.get((C.c.system==int(id)) & (C.c.id==int(c_id)))
        obj.name = name
        obj.save()
        return json({'is_error':False, 'error_text':"", 'html':name})
    
    @expose('add')
    def add(self, id):
        from uliweb.utils.generic import AddView
        from uliweb.orm import get_model
        from uliweb.form.layout import TableLayout
        from sqlalchemy.sql import and_, or_, not_
        
        Sysfunctioncategory= get_model('sysfunctioncategory')
#        System = get_model('system')
#        sys_obj=System.get(int(id))
        if not functions.has_role(request.user, 'sys_manager', system_id=id):
           flash('你不是系统管理员，无法添加系统功能点！')
           return redirect(url_for(self.__class__.list, id=id))
        def post_created_form(fcls, model):
            fcls.layout_class = TableLayout
            fcls.category.condition = (Sysfunctioncategory.c.system == id)
        
        def pre_save(data):
            data['system'] = int(id)
            if request.user.nickname:
                data['creator_user'] = request.user.nickname
            else:
                data['creator_user'] = request.user.username
                
        fields = ['category','sequence_number','function_name',
#                'system',
                'function_code','function_type',
                'business_rules',
#                'change_status',
                'business_degree','trading_route_origin',
                'route_origin_code','trading_route_downstream','route_downstream_code',
                'trading_frequency','daily_visit',
#                'creator_user',
                'subsystem_abbr','subsystem_name',
                'status',
#                'created_date',
#                'modified_date','modified_user',
#                'last_version_date','last_sittest_date','last_uattest_date',
#                'last_vttest_date',
                ]
        layout = [('category','sequence_number','function_name'),
#                'system',
                ('function_code','function_type'),
                'business_rules',
#                'change_status',
                ('business_degree','trading_route_origin'),
                ('route_origin_code','trading_route_downstream','route_downstream_code'),
                ('trading_frequency','daily_visit'),
#                'creator_user',
                ('subsystem_abbr','subsystem_name','status'),
#                'created_date',
#                'modified_date','modified_user','deleted',
#                'last_version_date','last_sittest_date','last_uattest_date',
#                'last_vttest_date',
                ]

        view = AddView('sysfunction', url_for(self.__class__.list,id=id), 
#                get_form_field = get_form_field,
                fields=fields,
                layout=layout,
                pre_save=pre_save,
                post_created_form=post_created_form,
                )
        return view.run()
        
        
#        return '<a href="/uploads/zhangclb/111027142947_%E6%8A%93%E5%9B%BE7.png">抓图7.png</a>'
    
    @expose('/systems/functions/view/<int:f_id>')
    def view(self, f_id):
        """
        系统功能点显示
        """
        
        from uliweb.utils.generic import DetailView, DetailTableLayout
        from uliweb import orm
        from uliweb.orm import get_model
        from uliweb.core.html import Tag
        from uliweb import request
        from sqlalchemy.sql import select,and_
        from uliweb import orm
        
#        System = get_model('system')
#        Task_dev = get_model('tasks_develop')
                
        obj = self.model.get(int(f_id))
        layout = [
                ('category','sequence_number','function_name'),
                ('system'),
                ('function_code','function_type'),
                ('business_rules'),
#                ('change_status',
                ('business_degree','trading_route_origin'),
                ('route_origin_code','trading_route_downstream','route_downstream_code'),
                ('trading_frequency','daily_visit'),
                ('creator_user'),
                ('subsystem_abbr','subsystem_name','status'),
                ('created_date'),
                ('modified_date','modified_user'),
#                'deleted',
                ('last_version_date','last_sittest_date','last_uattest_date'),
                ('last_vttest_date'),
            ]
        fields_convert_map = {}
        view = DetailView(self.model, obj=obj, 
            fields_convert_map=fields_convert_map, 
            layout=layout)
#        view.types_convert_map = {orm.BooleanProperty:boolean_convert}
        result = view.run()
        result.update({'system_id':obj._system_})
        return result

    

    @expose('edit/<int:f_id>')
    def edit(self, id,f_id):
        """
        系统功能点编辑
        """
        
        from uliweb.utils.generic import EditView
        from uliweb.orm import get_model,do_, NotFound
        from uliweb import request, redirect
        from uliweb.form.layout import TableLayout
        
        Sysfunctioncategory= get_model('sysfunctioncategory')
        
        if not functions.has_role(request.user, 'sys_manager', system_id=id):
           flash('你不是系统管理员，无法编辑该系统功能点！')
           return redirect(url_for(self.__class__.list, id=id))
        
        obj = self.model.get(int(f_id))
        def post_created_form(fcls, model, obj):
            fcls.layout_class = TableLayout
            fcls.category.condition = (Sysfunctioncategory.c.system == obj.system)
        fields = ['category','sequence_number','function_name',
                    'system',
                    'function_code','function_type',
                    'business_rules',
#                    'change_status',
                    'business_degree','trading_route_origin',
                    'route_origin_code','trading_route_downstream','route_downstream_code',
                    'trading_frequency','daily_visit',
                    'creator_user',
                    'subsystem_abbr','subsystem_name',
                    'created_date',
                    'modified_date','modified_user','status',
                    'last_version_date','last_sittest_date','last_uattest_date',
                    'last_vttest_date',
                ]
        static_fields = [
                        'creator_user','created_date','system',
                        'modified_date','modified_user',

                        ]
        layout = [
                    ('category','sequence_number','function_name'),
                    ('system'),
                    ('function_code','function_type'),
                    ('business_rules'),
#                    ('change_status',
                    ('business_degree','trading_route_origin'),
                    ('route_origin_code','trading_route_downstream','route_downstream_code'),
                    ('trading_frequency','daily_visit'),
#                        ('creator_user'),
                    ('subsystem_abbr','subsystem_name','status'),
#                        ('created_date'),
#                        ('modified_date','modified_user','deleted'),
                    ('last_version_date','last_sittest_date','last_uattest_date'),
                    ('last_vttest_date'),
                    ]
        view = EditView('sysfunction', ok_url=url_for(self.__class__.list,id=id), obj=obj,
#                    pre_save=pre_save, 
                    fields=fields,
                    layout = layout,
                    static_fields = static_fields,
#                    get_form_field = get_form_field,
                    post_created_form=post_created_form
                    )
        
        return view.run()
    
    @expose('delete/<int:f_id>')
#    @decorators.check_role('riskpoint_manager')
    def delete(self, id, f_id):
        """
        删除系统功能点
        """
        from uliweb.orm import get_model,do_, NotFound
        if not functions.has_role(request.user, 'sys_manager', system_id=id):
           flash('你不是系统管理员，无法删除该系统功能点！')
           return redirect(url_for(self.__class__.list, id=id))
        
        obj = self.model.get(int(f_id))
        if obj:
            obj.deleted = 1
            obj.save()
        return redirect(url_for(self.__class__.list, id=id))
    
    def _create_functions_list_query(self, url):
        """
        创建查询View
        """
        from uliweb.orm import get_model
        from uliweb.utils.generic import QueryView
        from uliweb.form import UnicodeField, SelectField
        
        from plugs.ui.jquery.jqcombobox.widgets import JQComboBoxField
        from plugs.ui.jquery.uimultiselect.widgets import UIMultiSelectField
        from query.forms import QueryForm
        from uliweb.utils.generic import ReferenceSelectField
        
        sequence_number = UnicodeField('功能点编号')
        status = UIMultiSelectField('启用状态', choices=settings.get_var('PARA/FUNCTION_USING_STATUS'))
        fields = ['category','system',('status', status),('sequence_number',sequence_number)]
        layout = [('category','system'),('status','sequence_number')]
        query = QueryView(self.model, ok_url=url, fields=fields, layout=layout, form_cls=QueryForm)
        return query
    
    @expose('/functions/list')
    def functions_list(self):
        """
        功能点列表
        """
        
        from uliweb.utils.generic import ListView, get_sort_field
        from uliweb.orm import get_model
        from uliweb.core.html import Tag
        query = self._create_functions_list_query(url_for(self.__class__.functions_list))
        c = query.run()
        pageno = int(request.values.get('page', 1)) - 1
        rows_per_page=int(request.values.get('rows', settings.get_var('PARA/ROWS_PER_PAGE', 10)))
        condition = None
#        condition = self.model.c.system == int(id)
#        condition = (self.model.c.deleted == 0) & condition
        if c.get('category'):
            condition = (self.model.c.category==c['category']) & condition
        if c.get('system'):
            condition = (self.model.c.system==c['system']) & condition
        if c.get('status'):
            condition = self.model.c.status.in_(c['status']) & condition
        if c.get('sequence_number'):
            condition = self.model.c.sequence_number.like('%'+c['sequence_number']+'%') & condition
        
        def sequence_number(value, obj):
            return str(Tag('a', obj.sequence_number, href="/systems/functions/view/%d" % obj.id))
        
        order_by = get_sort_field(self.model) or []
        fields_convert_map = {'sequence_number':sequence_number}
        view = ListView(self.model, condition=condition, 
            table_width=False, fields_convert_map=fields_convert_map, 
            order_by=order_by, rows_per_page=rows_per_page, pageno=pageno)
        if 'data' in request.values:
            return json(view.json())
        elif 'download' in request.values:
            return view.download('functions_list.xls', action='download', timeout=0,
                fields_convert_map=fields_convert_map, domain=settings.PARA.DOMAIN)
        else:
            result = view.run(head=True, body=False)
            result.update({'query_form':query.form, 'table':view, 'system_id':c.get('system')})
            return result
    @expose('sysfunction/import')
    def sysfunction_import(self,id):
        from uliweb.utils.generic import AddView
        from uliweb.orm import get_model
        from uliweb.utils.common import log
        from decimal import Decimal
        
        class ImportView(AddView):
            def on_success(self, data,aaa):
                from parse_excel import open_book
                try:
                    Sysfunction = get_model('sysfunction')
                    System = get_model('system')
                    Sysfunctioncategory = get_model('sysfunctioncategory')
                    
                    fields = ['category', 'sequence_number', 'system', 'function_name',
                        'function_code', ('function_type', 'PARA/FUNCTION_TYPE'),
                        'business_rules', ('business_degree','PARA/BUSINESS_DEGREE'),'trading_route_origin',
                        'route_origin_code', 'trading_route_downstream', 'route_downstream_code',
                        ('trading_frequency', 'PARA/YESNO'), 'daily_visit',
                        'subsystem_abbr', 'subsystem_name','P','Q','R','S',('status','PARA/FUNCTION_USING_STATUS'),'U','V','W','creator_user',
                        ]
                    f = {}  #字段列表信息
                    c = {}  #保存要转换值的字段信息，key为字段名，value为对应settings中的选项
                    def get_key(key, value):
                        """
                        用于反向根据值来获取key，如[('1', '高'), ('2', '低')]，根据'高'得到'1'
                        """
                        from uliweb import settings
                        
                        s = settings.get_var(key, [])
                        for k, v in s:
                            if isinstance(value, unicode):
                                value = value.encode('utf-8')
                            if isinstance(v, unicode):
                                v = value.encode('utf-8')
                                
                            if value == v:
                                return k
                        
                    for i, item in enumerate(fields):
                        if isinstance(item, (tuple, list)):
                            c[item[0]] = item[1]
                            f[i] = item[0]
                        else:
                            f[i] = item
                    last_sys = None
                    i = 0
                    for line in open_book(file_contents=data['func_file']['file'].read(), 
                        log=log, begin=1, fields=f):
                        i += 1
                        d = line.copy()
                        #process value convert
                        for k, v in c.iteritems():
                            if k in d:
                                d_v = d[k]
                                d[k] = get_key(v, d_v)
                                
#                        del d['sys_name']
                        if isinstance(d['daily_visit'],int) or isinstance(d['daily_visit'],float) or isinstance(d['daily_visit'],Decimal):
                            pass
                        elif not d['daily_visit'].strip():
                            d['daily_visit']=0
                        
                        abbr = d.pop('system')
                        if abbr:
                            s = System.get(System.c.abbr==abbr)
                            last_sys = s
                        if not last_sys:
                            flash('第%d行系统简称查询不到，请检查是否没有填写或大小写不一致' % i)
                            return redirect(url_for(SysFunctionView.list, id=id))
                        else:
                            if not (last_sys.id in (request.user.users_systems.ids())):
#                                print last_sys.id,[request.user.users_systems.ids()],(last_sys.id in (request.user.users_systems.ids()))
                                flash('你不是导入数据中的系统管理员，无法导入该系统系统功能点，请检查！')
                                return redirect(url_for(SysFunctionView.list, id=id))
                            
                            category = d.pop('category')
                            if category:
                               ca = Sysfunctioncategory.get(and_(Sysfunctioncategory.c.name==category,Sysfunctioncategory.c.system==last_sys.id))
                               d['category'] = ca.id
                            d['system'] = last_sys.id
                            if isinstance(d['sequence_number'],int):
                               d['sequence_number'] = str(d['sequence_number'])
                            d['sequence_number'] = last_sys.sys_id +'_'+ d['function_code']
                            row = Sysfunction.get(Sysfunction.c.sequence_number==d['sequence_number'])
                            if row:
                                row.update(**d)
                            else:
                                row = Sysfunction(**d)
                            row.save()
                    
                    flash('导入成功，共导入%d条记录' % i)
                    return redirect(url_for(SysFunctionView.list, id=id))
                except Exception, e:
                    log.exception(e)
                    flash('处理过程有问题，请与程序员联系')
                    return redirect(url_for(SysFunctionView.list, id=id))
        
#        def post_created_form(fcls, model):
#            System = get_model('system')
#            if request.user.department == '2':
#                fcls.system.query = request.user.users_systems.all()
#            elif request.user.department == '3':
#                fcls.system.query = System.all()
        
        from forms import SysFunctionImportForm
        if request.user.department in ['2', '3']:
            view = ImportView('sysfunction', url_for(SysFunctionView.list, id=id), fields=(), 
#                post_created_form=post_created_form, 
                form_cls=SysFunctionImportForm)
            return view.run()
        else:
            flash('你不是开发人员和测试人员，无法导入新测试功能点！')
            return redirect(url_for(SysFunctionView.list, id=id))
    
